#include <iostream>
#include "Connection.hpp"
#include "Listener.hpp"//#include "Connection.hpp"
#include "Reactor.hpp"
#include "Common.hpp"
#include "NetCol.hpp"
#include "Protocol.hpp"




int main(int argc, char* argv[])
{
    if(argc != 2)
    {
        std::cout << argv[0] << " port" << std::endl;
        exit(USERAGE_ERR);
    }

    LogModule::ConsoleLogStrategy();
    int port = std::stoi(argv[1]);//将端口转换为整形

    //创建业务处理对象
    std::shared_ptr<NetCol> col = std::make_shared<NetCol>();
    //创建协议的对象
    std::shared_ptr<Protocol> protocol = std::make_shared<Protocol>(
        //为协议注册回调方法,处理上层业务
        [&col](Request& req)->Response{
            return col->Excute(req);
        }
    );
    //创建Tcp套接字
    std::shared_ptr<Connection> conn = std::make_shared<Listener>(port);
    //注册套接字的回调函数,将缓冲区的数据交给上层
    conn->RegiserHandler(
        [&protocol](std::string& inbuffer)->std::string{

            LOG(LogLevel::FATAL) << "进入匿名函数";
            std::string result;
            while(true)
            {
                //收到的报文可能不止一个,我们一次性处理完
                std::string package;
                if(!protocol->Decode(inbuffer, &package))
                {
                    //说明已经解析不出一个完整的报文了
                    break;
                }
                //一定拿到了一个完整的报文
                result += protocol->Excute(package);
            }
            LOG(LogLevel::FATAL) << "结束匿名函数";
            //将处理完的结果返回给发送缓冲区准备发送
            return result;
        }
    );
    //创建Reactor反应堆对象(管理文件描述符和进行事件写入epoll内核和事件派发)
    std::unique_ptr<Reactor>  tsvr = std::make_unique<Reactor>();

    //要将服务器和连接绑定在一起
    tsvr->AddConnection(conn);

    //运行服务器
    tsvr->Loop();
    return 0;
}
